package com.it.tydic.estate.module.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.it.tydic.estate.common.util.CurrentUtil;
import com.it.tydic.estate.common.util.InstaIdGenerator;
import com.it.tydic.estate.common.util.TimeUtil;
import com.it.tydic.estate.module.mapper.inner.*;
import com.it.tydic.estate.module.model.inner.*;
import com.it.tydic.estate.module.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.util.StringUtil;

import java.util.*;

@Service
@Transactional
public class UserServiceImpl implements UserService {
    @Autowired
    private TbUserMapper tbUserMapper;

    @Autowired
    private TbUserRoleMapper tbUserRoleMapper;

    @Autowired
    private TbRoleMapper tbRoleMapper;

    @Autowired
    private TbLoginLogMapper tbLoginLogMapper;

    @Autowired
    private TbUserGroupMapper tbUserGroupMapper;

    @Autowired
    private TbGroupMapper tbGroupMapper;

    @Override
    public int deleteById(String id) {
        return tbUserMapper.deleteByPrimaryKey(id);
    }

    @Override
    public TbUser findById(String id) {
        TbUser tbUser = tbUserMapper.selectByPrimaryKey(id);
        if (tbUser != null) {
            Example example = new Example(TbUserRole.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("userId", id);
            List<TbUserRole> tbUserRoles = tbUserRoleMapper.selectByExample(example);
            List<String> roleIds = new ArrayList<>();
            for (TbUserRole tbUserRole : tbUserRoles) {
                roleIds.add(tbUserRole.getRoleId());
            }
            tbUser.setRoleIds(roleIds);
            Example groupExample = new Example(TbUserGroup.class);
            Example.Criteria groupCriteria = groupExample.createCriteria();
            groupCriteria.andEqualTo("userId", id);
            TbUserGroup userGroup = tbUserGroupMapper.selectOneByExample(groupExample);
            if (userGroup != null) {
                tbUser.setGroupId(userGroup.getGroupId());
            }
        }
        return tbUser;
    }

    @Override
    public TbUser findByUserName(String userName) {
        Example example = new Example(TbUser.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("userName", userName);
        return tbUserMapper.selectOneByExample(example);
    }

    @Override
    public int deleteByIds(List<String> idList) {
        Example example = new Example(TbUser.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andIn("userId", idList);
        return tbUserMapper.deleteByExample(example);
    }

    @Override
    public int addOrUpdate(TbUser tbUser) {
        int index = 0;
        String userId = CurrentUtil.getCurrentUserId();
        if (StringUtil.isNotEmpty(tbUser.getUserPassward())) {
            tbUser.setUserPassward("{bcrypt}" + new BCryptPasswordEncoder().encode(tbUser.getUserPassward()));
        }
        if (!tbUser.isMiddleStatus()) {
            tbUser.setStatus(1);
        }else{
            tbUser.setStatus(0);
        }
        if (StringUtil.isEmpty(tbUser.getUserId())) {

            int count=countUserNameByName(tbUser.getUserName());
            if(count > 0){
                return -1;
            }

            InstaIdGenerator idGenerator = new InstaIdGenerator();
            tbUser.setUserId(idGenerator.nextId(TimeUtil.timeGen()) + "");
            tbUser.setCreateTime(new Date());
            tbUser.setUpdateTime(new Date());
            tbUser.setCreateUser(userId);
            tbUser.setStatus(0);
            index = tbUserMapper.insert(tbUser);
        } else {
            tbUser.setUpdateTime(new Date());
            tbUser.setUpdateUser(userId);
            index = tbUserMapper.updateByPrimaryKeySelective(tbUser);
        }
        if (index == 1 && tbUser.getRoleIds() != null && tbUser.getRoleIds().size() > 0) {
            List<String> roleIds = tbUser.getRoleIds();
            Example example = new Example(TbUserRole.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("userId", tbUser.getUserId());
            tbUserRoleMapper.deleteByExample(example);
            InstaIdGenerator idGenerator = new InstaIdGenerator();
            for (String roleId : roleIds) {
                TbUserRole tbUserRole = new TbUserRole();
                tbUserRole.setRoleId(roleId);
                tbUserRole.setUserId(tbUser.getUserId());
                tbUserRole.setUserRoleId(idGenerator.nextId(TimeUtil.timeGen()) + "");
                tbUserRoleMapper.insertSelective(tbUserRole);
                index++;
            }
        }
        return index;
    }

    public int countUserNameByName(String name){
        Example example = new Example(TbUser.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("userName", name);
       return  tbUserMapper.selectCountByExample(example);
    }


    @Override
    public Map<String, Object> findAllByPage(Map<String, String> param) {
        Map<String, Object> map = new HashMap<>();
        String pageNum = param.get("pageNum");
        String pageSize = param.get("pageSize");
        if (StringUtil.isNotEmpty(pageNum) && StringUtil.isNotEmpty(pageSize)) {
            PageHelper.startPage(Integer.valueOf(pageNum), Integer.valueOf(pageSize));
            Example example = new Example(TbUser.class);
            example.setOrderByClause("UPDATE_TIME DESC");
            Example.Criteria criteria = example.createCriteria();
            String userName = param.get("userName");
            if (StringUtil.isNotEmpty(userName)) {
                criteria.andLike("userName", "%" + userName + "%");
            }
            PageInfo pageInfo = new PageInfo(tbUserMapper.selectByExample(example));
            List<TbUser> tbUserList = pageInfo.getList();
            if (tbUserList.size() > 0) {
                //设置用户角色名称
                setRoleName(tbUserList);
            }
            map.put("dataList", tbUserList);
            map.put("total", pageInfo.getTotal());
        } else {
            map.put("dataList", Collections.EMPTY_LIST);
            map.put("total", 0);
        }
        return map;
    }

    private void setRoleName(List<TbUser> tbUserList) {
        List<TbRole> tbroles = tbRoleMapper.selectAll();
        Map<String, TbRole> roleMap = new HashMap<>(tbroles.size());
        for (TbRole tbRole : tbroles) {
            roleMap.put(tbRole.getRoleId(), tbRole);
        }
        List<String> userIds = new ArrayList<>();
        for (TbUser tbUser : tbUserList) {
            userIds.add(tbUser.getUserId());
        }
        Example example = new Example(TbUserRole.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andIn("userId", userIds);
        List<TbUserRole> tbUserRoles = tbUserRoleMapper.selectByExample(example);
        Map<String, List<String>> roleName = new HashMap<>();
        Map<String, List<String>> roleIdMap = new HashMap<>();
        for (TbUserRole tbUserRole : tbUserRoles) {
            if (roleMap.get(tbUserRole.getRoleId()) != null) {
                if (!roleName.containsKey(tbUserRole.getUserId())) {
                    List<String> roleNameSList = new ArrayList<>();
                    roleNameSList.add(roleMap.get(tbUserRole.getRoleId()).getRoleName());
                    roleName.put(tbUserRole.getUserId(), roleNameSList);
                    List<String> roleIdList = new ArrayList<>();
                    roleIdList.add(tbUserRole.getRoleId());
                    roleIdMap.put(tbUserRole.getUserId(), roleIdList);
                } else {
                    roleName.get(tbUserRole.getUserId()).add(roleMap.get(tbUserRole.getRoleId()).getRoleName());
                    roleIdMap.get(tbUserRole.getUserId()).add(tbUserRole.getRoleId());
                }
            }
        }

        Example groupExample = new Example(TbUserGroup.class);
        Example.Criteria groupCriteria = groupExample.createCriteria();
        groupCriteria.andIn("userId", userIds);
        List<TbUserGroup> tbUserGroups = tbUserGroupMapper.selectByExample(groupExample);
        List<TbGroup> groups = tbGroupMapper.selectAll();
        Map<String, TbGroup> groupMap = new HashMap<>();
        for (TbGroup group : groups) {
            groupMap.put(group.getGroupId(), group);
        }
        Map<String, TbGroup> userGroupMap = new HashMap<>();
        for (TbUserGroup tbUserGroup : tbUserGroups) {
            userGroupMap.put(tbUserGroup.getUserId(), groupMap.get(tbUserGroup.getGroupId()));
        }
        for (TbUser tbUser : tbUserList) {
            if (tbUser.getStatus() == 0) {
                tbUser.setMiddleStatus(true);
            } else {
                tbUser.setMiddleStatus(false);
            }
            tbUser.setUserPassward(null);
            if (roleName.get(tbUser.getUserId()) != null && roleName.get(tbUser.getUserId()).size() > 0) {
                tbUser.setRoleName(JSON.toJSONString(roleName.get(tbUser.getUserId())));
            } else {
                tbUser.setRoleName("");
            }
            if (roleIdMap.size() > 0 && roleIdMap.get(tbUser.getUserId()) != null) {
                tbUser.setRoleIds(roleIdMap.get(tbUser.getUserId()));
            } else {
                tbUser.setRoleIds(Collections.EMPTY_LIST);
            }
            if (userGroupMap.size() > 0) {
                TbGroup group = userGroupMap.get(tbUser.getUserId());
                if (group != null) {
                    tbUser.setGroupId(group.getGroupId());
                    tbUser.setGroupName(group.getGroupName());
                }
            }
        }
    }

    @Override
    public int updateUser2Role(List<String> userIds, String roleId) {

        Example example = new Example(TbUserRole.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andIn("userId", userIds);
        tbUserRoleMapper.deleteByExample(example);

        InstaIdGenerator idGenerator = new InstaIdGenerator();
        int index = 0;
        for (String userId : userIds) {
            TbUserRole tbUserRole = new TbUserRole();
            tbUserRole.setRoleId(roleId);
            tbUserRole.setUserId(userId);
            tbUserRole.setUserRoleId(idGenerator.nextId(TimeUtil.timeGen()) + "");
            tbUserRoleMapper.insertSelective(tbUserRole);
            index++;
        }
        return index;
    }

    @Override
    public List<String> findRolesByUserId(String userId) {

        Example example = new Example(TbUserRole.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("userId", userId);
        List<TbUserRole> userRoles = tbUserRoleMapper.selectByExample(example);
        if (userRoles.size() > 0) {
            List<String> roleIds = new ArrayList<>();
            for (TbUserRole tbUserRole : userRoles) {
                roleIds.add(tbUserRole.getRoleId());
            }
            return roleIds;
        }
        return Collections.emptyList();
    }

    @Override
    public void batchInsertLoginLog(List<TbLoginLog> list) {
        tbLoginLogMapper.batchInsertLoginLog(list);
    }

    @Override
    public int updateUser2Group(List<String> userIds, String groupId) {
        Example example = new Example(TbUserGroup.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andIn("userId", userIds);
        tbUserGroupMapper.deleteByExample(example);

        InstaIdGenerator idGenerator = new InstaIdGenerator();
        int index = 0;
        for (String userId : userIds) {
            TbUserGroup tbUserGroup = new TbUserGroup();
            tbUserGroup.setGroupId(groupId);
            tbUserGroup.setUserId(userId);
            tbUserGroup.setUserGroupId(idGenerator.nextId(TimeUtil.timeGen()) + "");
            tbUserGroupMapper.insertSelective(tbUserGroup);
            index++;
        }
        return index;
    }
}
